#pragma once
#ifndef __G_COUNTER_H__
#define __G_COUNTER_H__

#include <atomic>

#include "GTypes.h"

namespace GUtil
{
	template <typename T = GUInt32>
	class GCounter
	{
	public:
		T Count;

		GCounter()
		{
			Count = 0;
		}
		
		~GCounter()
		{
		
		}
		
		operator T ()
		{
			return Count;
		}

		void SetCount(const T& Value)
		{
			Count = Value;
		}

		T GetCount() const
		{
			return Count;
		}
		
		T Decrement(T Value = 1)
		{
			Count -= Value;
		}

		T Increment(T Value = 1)
		{
			Count += Value;
		}

		void Reset( )
		{
			Count = 0;
		}

		bool operator == (const GCounter<T>& Other)
		{
			return Count == Other.Count;
		}

	};


	template <typename T = GUInt32>
	class GAtomicCounter
	{
	public:
		//! Change T to atomic
		volatile T Count;

		GAtomicCounter()
		{
			Count = 0;
		}
		
		~GAtomicCounter()
		{
		}
		
		operator T ()
		{
			return Count;
		}

		void SetCount(const T& Value)
		{
			Count = Value;
		}

		T GetCount() const
		{
			return Count;
		}

		T Decrement(T Value = 1)
		{
			return Count -= Value;
		}

		T Increment(T Value = 1)
		{
			return Count += Value;
		}

		void Reset()
		{
			Count = 0;
		}
		
		bool operator == (const T& Value) const
		{
			return GetCount() == Value;
		}

	};

};

#endif // __G_COUNTER_H__